package javase.chixing.io.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * A.java --- A.class --- 在JVM Class中
 * 通过字节码文件得到该类的结构 反射!!!
 *
 * Method: 修饰符 + 返回值 + 方法名 + 参数列表 + 异常
 * 修饰符 modifier (public + abstract + static + final + native...)
 */
class ReflectDemo {
    public static void main(String[] args) {
            //通过 studentClass 的到 Student 类的结构
            Class<Student> studentClass = Student.class;
            //只能获取 public 修饰的属性名
            Field[] fields = studentClass.getFields();
            for (Field field : fields) {
                System.out.println("属性: "+field.getName());
            }
            //能获取 指定类的所有 属性，不考虑修饰符问题
            Field[] declaredFields = studentClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("属性1.0: "+declaredField.getName());
            }
            //作用:获取所有的方法，包括父类的方法
            Method[] methods = studentClass.getMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
            }
            // 能够获取本类当中方法，但不能获得 继承的方法
            Method[] declaredMethods = studentClass.getDeclaredMethods();
            for (int i = 0; i < declaredMethods.length; i++) {
                //获取方法名
                System.out.print("方法名: "+declaredMethods[i].getName());
                //获取权限修饰符
                System.out.print(" 修饰符: "+declaredMethods[i].getModifiers());
                Class<?> returnType = declaredMethods[i].getReturnType();
                //获得返回值类型
                System.out.print(" 返回值类型: "+returnType);
                //获得形式参数类型
                Class<?>[] parameterTypes = declaredMethods[i].getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.print(" 获取参数类型: "+ parameterType);
                }
                //获得异常类型
                Class<?>[] exceptionTypes = declaredMethods[i].getExceptionTypes();
                for (Class<?> exceptionType : exceptionTypes) {
                    System.out.println(" 获得异常类型: "+ exceptionType);
                }
                //获取形参个数
                int parameterCount = declaredMethods[i].getParameterCount();
                System.out.print(" 形参个数: "+parameterCount);
                System.out.println();
            }
            //方法调用 （重点!!!）
            Method method = null;
        try {
            method = studentClass.getMethod("add", int.class, float.class, int.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        Student student = null;
        try {
            //对象当中 必须！！！ 要有无参构造
            student = studentClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        try {
            //对象 调用 方法 方法.invoke(对象,实际参数)
            System.out.println(method.invoke(student, 10, 9.9f,10));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //方法调用 --> 调用由static修饰的方法
        try {
            Class<?> student1= Class.forName("javase.chixing.io.reflect.Student");
            try {
                Method method1 = student1.getDeclaredMethod("study", int.class);
                try {
                    method1.invoke(null,1);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
